package test_201512;

import java.util.Scanner;

/*
 * 试题编号：	201512-3
试题名称：	画图
时间限制：	1.0s
内存限制：	256.0MB
问题描述：	
问题描述
　　用 ASCII 字符来画图是一件有趣的事情，并形成了一门被称为 ASCII Art 的艺术。
       例如，下图是用 ASCII 字符画出来的 CSPRO 字样。
　　..____.____..____..____...___..
　　./.___/.___||.._.\|.._.\./._.\.
　　|.|...\___.\|.|_).|.|_).|.|.|.|
　　|.|___.___).|..__/|.._.<|.|_|.|
　　.\____|____/|_|...|_|.\_\\___/.
　　本题要求编程实现一个用 ASCII 字符来画图的程序，支持以下两种操作：
　　 画线：给出两个端点的坐标，画一条连接这两个端点的线段。
       简便起见题目保证要画的每条线段都是水平或者竖直的。水平线段用字符 - 来画，竖直线段用字符 | 来画。
        如果一条水平线段和一条竖直线段在某个位置相交，则相交位置用字符 + 代替。
　　 填充：给出填充的起始位置坐标和需要填充的字符，从起始位置开始，
        用该字符填充相邻位置，直到遇到画布边缘或已经画好的线段。
        注意这里的相邻位置只需要考虑上下左右 4 个方向，如下图所示，字符 @ 只和 4 个字符 * 相邻。
　　.*.
　　*@*
　　.*.
输入格式
　　第1行有三个整数m, n和q。m和n分别表示画布的宽度和高度，以字符为单位。q表示画图操作的个数。
　　第2行至第q + 1行，每行是以下两种形式之一：
　　 0 x1 y1 x2 y2：表示画线段的操作，(x1, y1)和(x2, y2)分别是线段的两端，
          满足要么x1 = x2 且y1 ≠ y2，要么 y1 = y2 且 x1 ≠ x2。
　　 1 x y c：表示填充操作，(x, y)是起始位置，保证不会落在任何已有的线段上；
     c 为填充字符，是大小写字母。
　　画布的左下角是坐标为 (0, 0) 的位置，向右为x坐标增大的方向，向上为y坐标增大的方向。
        这q个操作按照数据给出的顺序依次执行。画布最初时所有位置都是字符 .（小数点）。
输出格式
　　输出有n行，每行m个字符，表示依次执行这q个操作后得到的画图结果。
样例输入
4 2 3
1 0 0 B
0 1 0 2 0
1 0 0 A
样例输出
AAAA
A--A
样例输入
16 13 9
0 3 1 12 1
0 12 1 12 3
0 12 3 6 3
0 6 3 6 9
0 6 9 12 9
0 12 9 12 11
0 12 11 3 11
0 3 11 3 1
1 4 2 C
样例输出
................
...+--------+...
...|CCCCCCCC|...
...|CC+-----+...
...|CC|.........
...|CC|.........
...|CC|.........
...|CC|.........
...|CC|.........
...|CC+-----+...
...|CCCCCCCC|...
...+--------+...
................
评测用例规模与约定
　　所有的评测用例满足：2 ≤ m, n ≤ 100，0 ≤ q ≤ 100，0 ≤ x < m
（x表示输入数据中所有位置的x坐标），0 ≤ y < n（y表示输入数据中所有位置的y坐标）。
 */

//暂时80分，显示错误？？？|改了一个判断，90分，运行错误
public class Main3 {
	static char[][] huabu;
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		int width = input.nextInt();// 画布宽度
		int height = input.nextInt();// 画布高度
		int q = input.nextInt();// 操作的个数

		// 初始化画布
		huabu = new char[height][width];
		for (int i = 0; i < huabu.length; i++) {
			for (int j = 0; j < huabu[0].length; j++) {
				huabu[i][j] = '.';
			}
		}
		input.nextLine();// 去除next或nextXX产生的回车
		// 接收并处理操作
		for (int i = 0; i < q; i++) {
			String cmdLine = input.nextLine();
			if (cmdLine.charAt(0) == '0') {// 画线段操作
				String[] position = cmdLine.split(" ");
				// 获得位置
				int x1 = Integer.parseInt(position[1]);
				int y1 = Integer.parseInt(position[2]);
				int x2 = Integer.parseInt(position[3]);
				int y2 = Integer.parseInt(position[4]);
				// 重新定大小(细节)
				int xMin = Math.min(x1, x2);
				int xMax = Math.max(x1, x2);
				int yMin = Math.min(y1, y2);
				int yMax = Math.max(y1, y2);
				if (xMin == xMax && yMin != yMax) {// 竖线
					for (int y = yMin; y <= yMax; y++) {// 注意画布坐标和数组下标的关系
						if (huabu[height - y - 1][xMin] == '-') {// x坐标和数组列列坐标一样，height-y坐标-1=数组行坐标
							huabu[height - y - 1][xMin] = '+';// 交叉情况
						} else if(huabu[height - y - 1][xMin] != '+'){//细节，划线的时候，可以把填充物也给划掉。。。，不考虑这个就是80分
							huabu[height - y - 1][xMin] = '|';
						}
					}

				} else if (yMin == yMax && xMin != xMax) {// 横线
					for (int x = xMin; x <= xMax; x++) {// 注意画布坐标和数组下标的关系
						if (huabu[height - yMin - 1][x] == '|') {// x坐标和数组列列坐标一样，height-y坐标-1=数组行坐标
							huabu[height - yMin - 1][x] = '+';// 交叉情况
						} else if(huabu[height - yMin - 1][x] != '+'){//细节，划线的时候，可以把填充物也给划掉。。。，不考虑这个就是80分
							huabu[height - yMin - 1][x] = '-';
						}
					}
				}

			} else if (cmdLine.charAt(0) == '1') {// 填充操作,要从上下左右四个方向进行填充
				String[] position = cmdLine.split(" ");
				int x = Integer.parseInt(position[1]);
				int y = Integer.parseInt(position[2]);
				char sign = position[3].charAt(0);
				fill(x, y, height, width, sign);

			}
		}
		// 输出画布
		for (int i = 0; i < huabu.length; i++) {
			for (int j = 0; j < huabu[0].length; j++) {
				System.out.print(huabu[i][j]);
			}
			System.out.println();
		}

		input.close();

	}

	/**
	 * DFS算法实现填充操作
	 * @param x      坐标
	 * @param y      坐标
	 * @param height 高度
	 * @param width  宽度
	 * @param sign   符号
	 * @param huabu  画布数组
	 */
	public static void fill(int x, int y, int height, int width, char sign) {
		// 四个方向，碰到边缘或线段则停止
		// 递归退出条件
		if (x < 0 || y < 0 || x > width - 1 || y > height - 1) {
			return;// 碰到边缘
		} else if (huabu[height - y - 1][x] == '-' || huabu[height - y - 1][x] == '|' || huabu[height - y - 1][x] == '+'
				|| huabu[height - y - 1][x] == sign) {
			return;// 碰到线段或重复操作时，例如往上迭代完后，向下的时候就会重复！！！
		} else {
			huabu[height - y - 1][x] = sign;
			fill(x, y + 1, height, width, sign);// 向上
			fill(x, y - 1, height, width, sign);// 向下
			fill(x + 1, y, height, width, sign);// 向右
			fill(x - 1, y, height, width, sign);// 向左
		}

	}

}
